20. Servlet 2

请求与相应

请求

定义

客户端向服务器发送请求报文。

类型

HttpServletRequest(这里以最终创建 Servlet 的方式讲解)

作用
  1. 获取请求参数。使用 getParamter(name),通过 name 获取请求参数。通过 getParamterValues(name) 可获取 name 值有多个的参数。
  2. 获取项目的虚拟路径(ServletContext 能获取真实路径)。使用 getContextPath() 可获取虚拟路径。
  3. 转发
  4. 域对象

GET 访问 http://localhost:8080/servlet2/Servlet2?age=19&option=1&option=2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 请求演示
// 1. 获取请求参数
String age = request.getParameter("age");
System.out.println(age); // 19
// 1. 获取请求参数
String[] option = request.getParameterValues("option");
for (String string : option) {
System.out.println(string); // 1 2
}

// 2. 获取虚拟路径
String contextPath = request.getContextPath();
System.out.println(contextPath); // /servlet2

//3. 转发
//3.1 先获取转发器
RequestDispatcher dispatcher = request.getRequestDispatcher("/login.html");
//3.2 再转发
dispatcher.forward(request, response);
}

响应

定义

服务器端向客户端发送响应报文。

类型

HttpServletResponse

作用
  1. 服务器端向客户端做出响应
  2. 重定向

POST 访问 http://localhost:8080/servlet2/Servlet2

1
2
3
4
5
6
7
8
9
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// // 响应演示
// // 1. 服务器端向客户端做出响应
// PrintWriter writer = response.getWriter();
// writer.write("hello"); //输出 hello

// 2. 重定向
response.sendRedirect("login.html"); // 重定向到 login.html
}

转发与重定向

  1. 转发地址栏不变,重定向地址栏改变
  2. 转发客户端只发送一次请求,重定向客户端发送两次请求
  3. 转发可以访问 WEB-INF 下的资源,重定向不能。 WEB-INF 目录属于私有目录(客户端无法直接访问)
  4. 转发可以携带 request 对象,重定向不能。

应用路径

web.xml 中的 path 路径(url)和转发的地址由服务器进行解析。/ 代表项目根目录,即 /项目名。
html 中的路径,例如 src,link,from 和 重定向由浏览器解析。/ 代表服务器根路径。即 8080 后面。
所以在重定向的时候,前面需要加上项目根目录,使用 request.getContextPath(); 可获得。

乱码问题

编码是将 字符 -> 二进制。解码是将二进制 -> 字符,乱码的原因编码和解码对应不上导致。服务端默认的编码和解码方式为 ISO-8859-1,浏览器编码可通过 <mate charset="utf-8"> 设置,解码默认为 GBK。

请求乱码

  1. post的解决方式为 request.setCharacterEncoding("utf-8");
  2. get请求需要将 tomcat 的 server.xml 中的端口号配置后面加上属性 URIEncoding="UTF-8"

响应乱码

  1. 因为浏览器默认是 GBK 解码。所以我们可以将两边的编码都统一为GBK。response.setCharacterEncoding("GBK");
  2. 第二种方式就是将两边都解码方式都统一为 UTF-8。 response.setContentType("text/html;charset=UTF-8");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.itguigu.servlet2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Servlet2 extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
System.out.println(name);
// 解决响应乱码1
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write(name);
}


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决 POST 乱码
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
System.out.println(name);
// 解决响应乱码2
response.setCharacterEncoding("GBK");
PrintWriter writer = response.getWriter();
writer.write(name);
}
}